/*
 * Copyright 2012 NJUT  qixiaobo. All rights reserved.
 */
package com.fujitsu.nanjing.tieba.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fujitsu.nanjing.tieba.base.BaseService;
import com.fujitsu.nanjing.tieba.common.Param;
import com.fujitsu.nanjing.tieba.constrant.CommonParamter;
import com.fujitsu.nanjing.tieba.ibator.CoreGroup;
import com.fujitsu.nanjing.tieba.ibator.CoreUser;
import com.fujitsu.nanjing.tieba.ibator.CoreUserCriteria;
import com.fujitsu.nanjing.tieba.model.User;

/**
 * UserService.java
 * 
 * @author Qixiaobo-win8
 */

@Service
@Transactional
public class UserService extends BaseService<CoreUser, CoreUserCriteria> {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(UserService.class);

	@Resource
	private User user;
	@Resource
	private GroupService groupService;
	@Override
	public CoreUser findById(String id) {
		return user.selectByPrimaryKey(id);
	}

	@Override
	public CoreUser insert(CoreUser t) {
		if (t.getNickname() == null) {
			t.setNickname(t.getUserid());
		}
		t.setGroupid(CommonParamter.新手上路);
		t.setCredits(0);
		addCredits(t, CommonParamter.初始积分);
		t.setPosts(0);
		t.setLogincount((byte) 0);
		t.setLastvisited(new Date());
		user.insertSelective(t);
		return t;

	}

	@Override
	public void update(CoreUser t) {
		t.setUpdatetime(new Date());
		user.updateByPrimaryKeySelective(t);
	}

	@Override
	public void delete(CoreUser t) {
		user.deleteByPrimaryKey(t.getUserid());

	}

	public int findByEmail(String Email) {
		CoreUserCriteria example = new CoreUserCriteria();
		example.createCriteria().andEmailEqualTo(Email);
		return user.countByExample(example);
	}
	public CoreUser findUserByEmail(String Email) {
		CoreUserCriteria example = new CoreUserCriteria();
		example.createCriteria().andEmailEqualTo(Email);
		List<CoreUser> users = user.selectByExample(example);
		if (users == null || users.size() == 0) {
			return null;
		}
		return users.get(0);
	}

	/**
	 * 获取用户昵称，如果为空，则返回用户id
	 ***/
	public String getUserName(String userId) {
		CoreUser coreUser = user.selectByPrimaryKey(userId);
		return coreUser.getNickname() == null ? coreUser.getUserid() : coreUser
				.getNickname();
	}

	public CoreUser findByIdAndPwd(String userId, String pwd) {
		CoreUserCriteria example = new CoreUserCriteria();
		example.createCriteria().andPwdEqualTo(pwd).andUseridEqualTo(userId);
		List<CoreUser> userList = user.selectByExample(example);
		if (userList != null && userList.size() != 0) {
			return userList.get(0);
		}
		return null;

	}

	/** 由于登陆需要更改相关数据 **/
	public void updateWhileLogin(CoreUser coreUser, String CookieValue) {
		coreUser.setLastvisited(new Date());
		coreUser.setVisitcount(coreUser.getVisitcount() + 1);
		update(coreUser);
	}

	/**
	 * 发帖或者回复调用此方法
	 * */
	public void updateUserPosts(String userId) {
		CoreUser coreUser = findById(userId);
		coreUser.setPosts(coreUser.getPosts() == null
				? 0
				: coreUser.getPosts() + 1);
		addCredits(coreUser, CommonParamter.发帖基本分);
		update(coreUser);
	}

	/**
	 * 发生错误时更新用户状态
	 * */
	public void updateUserStateWhileError(CoreUser coreUser) {
		if (checkUserState(coreUser.getUserid())) {
			// 正常状态
			int errorTimes = coreUser.getLogincount() + 1;
			if (errorTimes == CommonParamter.ERROR_MAX_TIMES) {
				coreUser.setLoginexpire(new Date());
			}
			update(coreUser);
		} else {
			// 账户被锁定
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(coreUser.getLoginexpire());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			if (new Date().before(calendar.getTime()))
				coreUser.setLogincount((byte) 0);
			update(coreUser);
		}
	}
	/** 用户密码正确时调用 */
	public void updateUserStateWhileNomal(CoreUser user) {
		if (!user.getState().equals(CommonParamter.正常)) {
			user.setState(CommonParamter.正常);
			update(user);
		}
	}
	/**
	 * 
	 * 检验用户状态，true表示正常，false表示锁定
	 * */
	public boolean checkUserState(String userId) {
		CoreUser user = findById(userId);
		// 兼容老数据
		if (user.getLogincount() >= CommonParamter.ERROR_MAX_TIMES) {
			return false;
		}
		return true;
	}

	public List<CoreUser> findUsersWithPageNum(int offset, String orderCause,
			String whereCause, boolean isFind) {
		CoreUserCriteria example = new CoreUserCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		if (offset > 0) {
			example.setMysqlOffset((offset - 1) * CommonParamter.默认分页长度);
		}
		example.setOrderByClause(orderCause);
		if (isFind) {
			example.createCriteria().andUseridLike(whereCause);
		}
		return user.selectByExample(example);
	}
	public List<CoreUser> findUsersWithPageNum(int offset) {
		return findUsersWithPageNum(offset, CommonParamter.默认排序条件, null, false);
	}
	public List<CoreUser> findUsersWithPageNumAndFilter(int offset,
			String filter) {
		return findUsersWithPageNum(offset, CommonParamter.默认排序条件, filter, true);
	}
	public int findPageCountWithFilter(String filter) {
		return findPageCount(filter, true);
	}
	public int countByUserId(String whereCause, boolean isFind) {
		CoreUserCriteria example = new CoreUserCriteria();
		if (isFind) {
			example.createCriteria().andUseridLike(whereCause);
		}
		return user.countByExample(example);
	}

	public int findPageCount(String whereCause, boolean isFind) {
		int pageCount = (int) Math.ceil((double) countByUserId(whereCause,
				isFind) / CommonParamter.默认分页长度);
		if (pageCount == 0) {
			pageCount = 1;
		}
		return pageCount;
	}
	/** score 可以为负 */
	public void addCredits(String userid, int score) {
		CoreUser coreUser = findById(userid);
		if (coreUser != null) {
			coreUser.setCredits(coreUser.getCredits() + score);
			if (checkUserGroup(coreUser)) {
				coreUser.setGroupid(groupService.findCeilGroupId(coreUser
						.getCredits()));
				update(coreUser);
			}
			return;
		}
		logger.warn("UserId:" + userid + "用户" + score + "分失败！");
	}
	/** score 可以为负 ,此处没有提交更改，需要自行update */
	public void addCredits(CoreUser coreUser, int score) {
		coreUser.setCredits(coreUser.getCredits() + score);
		if (checkUserGroup(coreUser)) {
			coreUser.setGroupid(groupService.findCeilGroupId(coreUser
					.getCredits()));
			update(coreUser);
		}
	}
	/**
	 * @return true 表示为用户类型 false表示为管理类型
	 * */
	public boolean checkUserGroup(CoreUser coreUser) {
		String groupId = coreUser.getGroupid();
		return groupService.isUserType(groupId);
	}
	/**
	 * 在网页上展现
	 * */
	public List<Param> initGender() {

		List<Param> params = new ArrayList<Param>();
		// 没有放在数据库中，此处硬编码
		Param param = new Param();
		param.setText("男");
		param.setValue("m");
		params.add(param);
		param = new Param();
		param.setText(" 女");
		param.setValue("f");
		params.add(param);
		param = new Param();
		param.setText("保密");
		param.setValue("u");
		params.add(param);
		return params;

	}

	public boolean isExist(String userId) {
		CoreUserCriteria example = new CoreUserCriteria();
		example.createCriteria().andUseridEqualTo(userId);
		return user.countByExample(example) > 0;
	}

	public int countUsers() {
		CoreUserCriteria example = new CoreUserCriteria();
		example.createCriteria();
		return user.countByExample(example);
	}
	public int countUsersAfterTime(Date time) {
		CoreUserCriteria example = new CoreUserCriteria();
		example.createCriteria().andCreatetimeGreaterThanOrEqualTo(time);
		return user.countByExample(example);
	}
	public int countTopicUsers() {
		CoreUserCriteria example = new CoreUserCriteria();
		example.createCriteria().andPostsGreaterThan(0);
		return user.countByExample(example);
	}

	public int countAdmins() {
		CoreUserCriteria example = new CoreUserCriteria();
		List<String> values = new ArrayList<String>();
		for (CoreGroup group : groupService.findAdminGroups()) {
			values.add(group.getGroupid());
		}
		example.createCriteria().andGroupidIn(values);
		return user.countByExample(example);
	}
	public List<CoreUser> findAdmins() {
		CoreUserCriteria example = new CoreUserCriteria();
		List<String> values = new ArrayList<String>();
		for (CoreGroup group : groupService.findAdminGroups()) {
			values.add(group.getGroupid());
		}
		example.createCriteria().andGroupidIn(values);
		return user.selectByExample(example);
	}
	public List<CoreUser> findTopCreditsUsers() {
		CoreUserCriteria example = new CoreUserCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		example.setOrderByClause("credits desc");
		return user.selectByExample(example);
	}
	public List<CoreUser> findTopPostsUsers() {
		CoreUserCriteria example = new CoreUserCriteria();
		example.setMysqlLength(CommonParamter.默认分页长度);
		example.setOrderByClause("posts desc");
		return user.selectByExample(example);
	}
	public int countMonthNewUsers() {
		return user.countMonthNewUsers();
	}
	public Date setPwdExpired(CoreUser t) {
		Date now = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(now);
		calendar.add(Calendar.DAY_OF_MONTH, 1);
		t.setSetpwdexpire(calendar.getTime());
		update(t);
		return calendar.getTime();

	}
	public boolean checkValid(String userId, String date) {
		CoreUser coreUser = findById(userId);
		if (coreUser == null) {
			return false;
		}
		Date now = new Date();
		if (now.before(coreUser.getSetpwdexpire())) {
			if (coreUser.getSetpwdexpire().toString().equals(date)) {
				coreUser.setSetpwdexpire(now);
				update(coreUser);
				return true;
			}
			return false;
		}
		return false;
	}
	public List<CoreUser> findLongTimeNoSee(int offset, Date time) {
		CoreUserCriteria example = new CoreUserCriteria();
		example.setDistinct(true);
		example.setMysqlLength(CommonParamter.默认分页长度);
		example.setOrderByClause(CommonParamter.默认排序条件);
		example.setMysqlOffset(offset);
		example.createCriteria().andStateEqualTo(CommonParamter.正常)
				.andLastvisitedLessThan(time);
		return user.selectByExample(example);
	}
}
